//! 迭代器
//! iter()函数返回对集合中每个元素的引⽤，使集合保持不变，并在循环后可以重⽤。
//! into_iter()		函数
//! 此函数将集合中的值移动到⼀个iter对象中，即该集合已被使⽤，并且不再可重⽤。

use std::collections::HashMap;

//Rust有一个for循环能够依次对迭代器的任意元素进行访问，即：
#[test]
pub fn iterator_demo1(){
    for i in 1..10 {
        println!("{}", i);
    }
}
//(1..10) 其本身是一个迭代器，我们能对这个迭代器调用 .next() 方法，因此，for循环就能完整的遍历一个循环
//而对于Vec来说:

#[test]
pub fn iterator_demo2(){
    let values = vec![1,2,3];
    for x in values {
        println!("{}", x);
    }
}
//在上面的代码中，我们并没有显式地将一个Vec转换成一个迭代器，那么它是如何工作的呢？现在就打开标准库翻api的同学可能发现了
// ,Vec本身并没有实现 Iterator ，也就是说，你无法对Vec本身调用 .next() 方法。但是，我们在搜索的时候，发现了Vec实现了
// IntoIterator 的 trait。
//
// 其实，for循环真正循环的，并不是一个迭代器(Iterator)，真正在这个语法糖里起作用的，是 IntoIterator 这个 trait。


//无限迭代器,Rust支持通过省略高位的形式生成一个无限长度的自增序列，即：
#[test]
pub fn iterator_demo3(){
    let inf_seq = (1..).into_iter();
}
//不过不用担心这个无限增长的序列撑爆你的内存，占用你的CPU，因为适配器的惰性的特性，它本身是安全的，
// 除非你对这个序列进行collect或者fold！ 不过，我想聪明如你，不会犯这种错误吧！ 因此，想要应用这个，
// 你需要用take或者take_while来截断他，必须？ 除非你将它当作一个生成器。当然了，那就是另外一个故事了。


#[test]
pub fn iterator_demo4(){

    let mut v1 = vec![1, 3, 4];
    let v1_iter = v1.iter(); //不会获取所有权

    //不可变引用
    for val in v1_iter {
        println!("{}", val);
    }
    println!("{}", v1[1]);

    //迭代可变引用，不会获取所有权，可以通过引用修改元素的值
    let mut_iter = v1.iter_mut();
    for val in mut_iter {
        *val = 10;
    }


    let v2_iter = v1.into_iter(); //会获取所有权，v1失效
    for val in v2_iter {
        println!("{}", val);
    }
    //println!("{}", v1[2]);
}

#[test]
pub fn iterator_demo5(){
    let v = vec![1, 3, 3];
    let v2: Vec<_> = v.iter().map(|x| x + 1).collect();
    println!("{:?}", v2);

    let v3: Vec<_> = v.iter().filter(|x| **x == 3).collect();
    println!("{:?}", v3);
}

/*自定义迭代器*/

struct Counter{
    count: i32,
}
impl Counter {
    fn new() -> Counter {
        Counter{count: 0}
    }
}
//实现Iterator这个trait
impl Iterator for Counter {
    type Item = i32;

    fn next(&mut self) -> Option<Self::Item> {
        if self.count < 5 {
            self.count += 1;
            Some(self.count)
        }else {
            None
        }
    }
}

#[test]
pub fn iterator_demo6(){
    let counter = Counter::new();
    /*    for i in counter {
            println!("{}", i); //1, 2, 3, 4, 5
        }*/
    let counter2 = Counter::new().skip(2);
    /*    for i in counter2 {
            println!("{}", i); // 3, 4, 5
        }*/

    //zip：zipper（拉链），将两个迭代器对应元素合成一个元组，多余的舍弃
    let r: i32 = counter.zip(counter2).map(|(a, b)| {
        println!("{},{}", a, b);
        a * b
    }).sum();
    println!("{}", r)
}

//消费者
// 就像所有人都熟知的生产者消费者模型，迭代器负责生产，而消费者则负责将生产出来的东西最终做一个转化。
// 一个典型的消费者就是collect。前面我们写过collect的相关操作，它负责将迭代器里面的所有数据取出
//收集
#[test]
pub fn iterator_demo7(){
    let v: Vec<i32> = (1..20).collect();
    let v = (1..20).collect::<Vec<i32>>();
}

//fold,看源码和注释
#[test]
pub fn iterator_demo8(){
    let m = (1..4).fold(2_u64, |mul,x| mul * x);
    println!("{}", m);
    //过程:
    //mul（初始值为2）   元素       返回结果（作为下一次迭代的mul）
    // 2             * 1 =       2
    // 2             * 2 =       4
    // 4             * 3 =       12
    //最终结果为12
}

//适配器
//我们所熟知的生产消费的模型里，生产者所生产的东西不一定都会被消费者买账，因此，需要对原有的产品进行再组装。
// 这个再组装的过程，就是适配器。因为适配器返回的是一个新的迭代器，所以可以直接用链式请求一直写下去

#[test]
pub fn iterator_demo9(){
    //映射
    let v = (1..2).map(|x| x + 1).collect::<Vec<i32>>();
    //过滤
    let v: Vec<_> = (1..20).filter(|x| x%2 == 0).collect();

}

//skip和take
//take(n)的作用是取前n个元素，而skip(n)正好相反，跳过前n个元素
#[test]
pub fn iterator_demo10(){
    let v = vec![1, 2, 3, 4, 5, 6];
    let v_take = v.iter()
        .cloned()
        .take(2)
        .collect::<Vec<_>>();

    let v_skip: Vec<_> = v.iter()
        .cloned()
        .skip(2)
        .collect();
}

//zip是一个适配器，他的作用就是将两个迭代器的内容压缩到一起，形成 Iterator<Item=(ValueFromA, ValueFromB)> 这样的新的迭代器；
#[test]
pub  fn iterator_demo11(){
    let names = vec!["WaySLOG", "Mike", "Elton"];
    let scores = vec![60, 80, 100];
    let score_map: HashMap<_, _> = names.iter()
        .zip(scores.iter())
        .collect();
    println!("{:?}", score_map);
}
